from machine import I2C, Pin
import time

class PCF8563:
    def __init__(self, i2c, address=0x51):
        self.i2c = i2c
        self.address = address
        
    def _dec2bcd(self, value):
        return (value // 10) << 4 | (value % 10)
    
    def _bcd2dec(self, value):
        return ((value >> 4) * 10) + (value & 0x0F)
    
    def datetime(self, datetime=None):
        if datetime is None:
            # 读取时间
            data = self.i2c.readfrom_mem(self.address, 0x02, 7)
            seconds = self._bcd2dec(data[0] & 0x7F)
            minutes = self._bcd2dec(data[1] & 0x7F)
            hours = self._bcd2dec(data[2] & 0x3F)
            day = self._bcd2dec(data[3] & 0x3F)
            weekday = self._bcd2dec(data[4] & 0x07)
            month = self._bcd2dec(data[5] & 0x1F)
            year = self._bcd2dec(data[6]) + 2000
            
            return (year, month, day, weekday, hours, minutes, seconds, 0)
        else:
            # 设置时间
            year, month, day, weekday, hours, minutes, seconds, _ = datetime
            
            data = bytearray(7)
            data[0] = self._dec2bcd(seconds) & 0x7F
            data[1] = self._dec2bcd(minutes) & 0x7F
            data[2] = self._dec2bcd(hours) & 0x3F
            data[3] = self._dec2bcd(day) & 0x3F
            data[4] = self._dec2bcd(weekday) & 0x07
            data[5] = self._dec2bcd(month) & 0x1F
            data[6] = self._dec2bcd(year - 2000)
            
            self.i2c.writeto_mem(self.address, 0x02, data)
    
    def alarm(self, minutes=None, hours=None, day=None, weekday=None):
        # 设置闹钟
        if minutes is not None or hours is not None or day is not None or weekday is not None:
            data = bytearray(4)
            data[0] = self._dec2bcd(minutes) & 0x7F if minutes is not None else 0x80
            data[1] = self._dec2bcd(hours) & 0x3F if hours is not None else 0x80
            data[2] = self._dec2bcd(day) & 0x3F if day is not None else 0x80
            data[3] = self._dec2bcd(weekday) & 0x07 if weekday is not None else 0x80
            
            self.i2c.writeto_mem(self.address, 0x09, data)